﻿using System;
using System.Collections.Generic;
using System.Web.Services;
using ClickLand.CorporacionPlaza.Comunes.Entidades;
using ClickLand.CorporacionPlaza.Comunes.EntidadesDto;
using ClickLand.CorporacionPlaza.LogicaNegocio.Contratos;
using ClickLand.CorporacionPlaza.LogicaNegocio.Logica;
using ClickLand.CorporacionPlaza.Servicio.Contratos;
using ClickLand.CorporacionPlaza.Traductores;

namespace ClickLand.CorporacionPlaza.Servicio.Implementacion
{
    /// <summary> Clase que implementa el contrato con las 
    /// operaciones definidas para el servicio </summary>
    public class CorporacionPlazaWS:ICorporacionPlazaWS
    {
        #region Atributos

        /// <summary> Atributos que posee la definicion de la logica de negocio </summary>
        private readonly ILogicaCorporacionPlaza _logica; 
        #endregion

        #region Constructor

        /// <summary> Constructor donde se inicializa los atributos </summary>
        public CorporacionPlazaWS()
        {
            _logica = new LogicaCorporacionPlaza();
        }

        #endregion

        #region Implementacion

        /// <summary> Metodo de prueba para seguir de ejemplo como se realizan la declaracion de los mismos </summary>
        /// <returns>true si funciona false sino</returns>
        [WebMethod(Description = "Metodo de prueba para seguir de ejemplo como se realizan la declaracion de los mismos.")]
        public bool ServicioPrueba()
        {
            return _logica.Prueba();
        }


        /// <summary> Metodo que almacena los datos de un cliente </summary>
        /// <param name="cliente">datos del cliente a almacenar</param>
        /// <returns>true si la transaccion fue exitosa false sino</returns>
        [WebMethod(Description = "Metodo que almacena los datos de un cliente .")]
        public bool AgregarEditarCliente(ClienteDto cliente)
        {
            var obj = TraductorCliente.ObtenerEntidad(cliente);
            obj.Contratos = TraductorContrato.ObtenerListaEntidad(cliente.Contratos);
            return _logica.AgregarEditarCliente(obj);
        }


        /// <summary> Metodo que consulta los clientes dados los parametros indicados </summary>
        /// <param name="parametros">datos para la consulta</param>
        /// <returns>lista de cliente</returns>
        [WebMethod(Description = "Metodo que consulta los clientes dados los parametros indicados.")]
        public List<ClienteDto> ConsultarCliente(ClienteDto parametros)
        {
            var obj = TraductorCliente.ObtenerEntidad(parametros);
            obj.Contratos = TraductorContrato.ObtenerListaEntidad(parametros.Contratos);
            var consulta = _logica.ConsultarCliente(obj);

            var retorno = TraductorCliente.ObtenerListaDto(consulta);
            for (var i = 0; i < consulta.Count; i++)
                if (consulta[i].Contratos != null)
                    retorno[i].Contratos = TraductorContrato.ObtenerListaDto(consulta[i].Contratos);
            return retorno;
        }


        /// <summary> Metodo que con almacena los datos de un contrato nuevo </summary>
        /// <param name="contrato">datos del contrato a almacenar</param>
        /// <returns>true si realizo la insercion false sino</returns>
        [WebMethod(Description = "Metodo que con almacena los datos de un contrato nuevo.")]
        public bool AgregarContrato(ContratoDto contrato)
        {
            Contrato entidad = TraductorContrato.ObtenerEntidad(contrato);
            entidad.Fiadores = TraductorFiador.ObtenerListaEntidad(contrato.Fiadores);
            entidad.Pension = TraductorPension.ObtenerEntidad(contrato.Pension);
            entidad.Pension.Contrato = entidad;
            entidad.Pension.ContratoPensiones =
                TraductorContratoPension.ObtenerListaEntidad(contrato.Pension.ContratoPensiones);

            foreach (var obj in entidad.Pension.ContratoPensiones)
            {
                obj.Pension = entidad.Pension;
                obj.Contrato = entidad;
            }
            entidad.Polizas = TraductorPoliza.ObtenerListaEntidad(contrato.Polizas);
            entidad.Cliente = TraductorCliente.ObtenerEntidad(contrato.Cliente);
            entidad.Establecimiento = TraductorEstablecimiento.ObtenerEntidad(contrato.Establecimiento);
            entidad.Ventas = TraductorVenta.ObtenerListaEntidad(contrato.Ventas);
            if (contrato.Garantia != null)
                entidad.Garantia = TraductorGarantia.ObtenerEntidad(contrato.Garantia);

            return _logica.AgregarEditarContrato(entidad);
        }


        /// <summary> Metodo que Consulta los establecimientos </summary>
        /// <param name="establecimiento">Parametros para la busqueda</param>
        /// <returns>Lista de todos los establecimientos</returns>
        [WebMethod(Description = "Metodo que Consulta los establecimientos .")]
        public List<EstablecimientoDto> ConsultarTodosEstablecimientos(EstablecimientoDto establecimiento)
        {
            var obj = TraductorEstablecimiento.ObtenerEntidad(establecimiento);
            obj.Tipo = TraductorTipoEstablecimiento.ObtenerEntidad(establecimiento.Tipo);
            var consulta = _logica.ConsultarTodosEstablecimientos(obj);
            var retorno = TraductorEstablecimiento.ObtenerListaDto(consulta);

            for (var i = 0; i < consulta.Count; i++)
                retorno[i].Tipo = TraductorTipoEstablecimiento.ObtenerDto(consulta[i].Tipo);
            return retorno;
        }


        /// <summary> Metodo que Consulta los contratos dado los parametros indicados </summary>
        /// <param name="parametros">Parametros para la busqueda</param>
        /// <returns>Lista de todos los establecimientos</returns>
        [WebMethod(Description = "Metodo que Consulta los datos de un contrato .")]
        public List<ContratoDto> ConsultarContrato(ContratoDto parametros)
        {
            Contrato entidad = TraductorContrato.ObtenerEntidad(parametros);
            if(parametros.Cliente != null)
                entidad.Cliente = TraductorCliente.ObtenerEntidad(parametros.Cliente);
            if(parametros.Establecimiento != null)
                entidad.Establecimiento = TraductorEstablecimiento.ObtenerEntidad(parametros.Establecimiento);
            
            if(parametros.Garantia != null)
                entidad.Garantia = TraductorGarantia.ObtenerEntidad(parametros.Garantia);

            var consulta = _logica.ConsultarContrato(entidad);
            var retorno = TraductorContrato.ObtenerListaDto(consulta);

            for (var i = 0; i < retorno.Count; i++ )
            {
                if (consulta[i].Fiadores != null)
                    retorno[i].Fiadores = TraductorFiador.ObtenerListaDto(consulta[i].Fiadores);
                if (consulta[i].Pension != null)
                {
                    retorno[i].Pension = TraductorPension.ObtenerDto(consulta[i].Pension);
                    if (consulta[i].Pension.ContratoPensiones != null)
                    {
                        retorno[i].Pension.ContratoPensiones =
                            TraductorContratoPension.ObtenerListaDto(consulta[i].Pension.ContratoPensiones);

                    }
                }
                if (consulta[i].Polizas != null)
                    retorno[i].Polizas = TraductorPoliza.ObtenerListaDto(consulta[i].Polizas);

                if (consulta[i].Cliente != null)
                    retorno[i].Cliente = TraductorCliente.ObtenerDto(consulta[i].Cliente);


                if (consulta[i].Establecimiento != null)
                {

                    retorno[i].Establecimiento = TraductorEstablecimiento.ObtenerDto(consulta[i].Establecimiento);
                    retorno[i].Establecimiento.Tipo =
                        TraductorTipoEstablecimiento.ObtenerDto(consulta[i].Establecimiento.Tipo);
                }

                if (consulta[i].Ventas != null)
                    retorno[i].Ventas = TraductorVenta.ObtenerListaDto(consulta[i].Ventas);

                if (consulta[i].Garantia != null)
                retorno[i].Garantia = TraductorGarantia.ObtenerDto(consulta[i].Garantia);
            }

            return retorno;

        }


        /// <summary> Metodo que Consulta los contratos dado los parametros indicados </summary>
        /// <param name="id">Parametros para la busqueda</param>
        /// <returns>Lista de todos los establecimientos</returns>
        [WebMethod(Description = "Metodo que Agrega o edita la informacion de un establecimientos .")]
        public ContratoDto ConsultarContratoId(long id)
        {
            var contrato = _logica.ConsultarContrato(id);
            var retorno = TraductorContrato.ObtenerDto(contrato);
            if (contrato.Fiadores != null)
                retorno.Fiadores = TraductorFiador.ObtenerListaDto(contrato.Fiadores);
            if (contrato.Pension != null)
            {
                retorno.Pension = TraductorPension.ObtenerDto(contrato.Pension);
                if (contrato.Pension.ContratoPensiones != null)
                {
                    retorno.Pension.ContratoPensiones =
                        TraductorContratoPension.ObtenerListaDto(contrato.Pension.ContratoPensiones);


                    foreach (var obj in retorno.Pension.ContratoPensiones)
                        obj.Pension = retorno.Pension;
                }
            }
            if (contrato.Polizas != null)
                retorno.Polizas = TraductorPoliza.ObtenerListaDto(contrato.Polizas);

            if (contrato.Cliente != null)
                retorno.Cliente = TraductorCliente.ObtenerDto(contrato.Cliente);


            if (contrato.Establecimiento != null)
                retorno.Establecimiento = TraductorEstablecimiento.ObtenerDto(contrato.Establecimiento);

            if (contrato.Ventas != null)
                retorno.Ventas = TraductorVenta.ObtenerListaDto(contrato.Ventas);

            if (contrato.Garantia != null)
                retorno.Garantia = TraductorGarantia.ObtenerDto(contrato.Garantia);
            return retorno;
        }


        /// <summary> Metodo que consulta todos los establecimientos libres dentro de un limite de fecha </summary>
        /// <param name="fechaInicio">fecha de inicio de la busqueda</param>
        /// <param name="fechaFin"> </param>
        /// <returns>Lista de establecimientos que concuerdan con la fecha</returns>
        [WebMethod(Description = " Metodo que consulta todos los establecimientos libres dentro de un limite de fecha.")]
        public List<EstablecimientoDto> ConsultarEstablecimientoLibres(DateTime fechaInicio, DateTime fechaFin)
        {
            var lista = _logica.ConsultarEstablecimientosLibres(fechaInicio, fechaFin);
            var retorno = TraductorEstablecimiento.ObtenerListaDto(lista);
            for (int i = 0; i < lista.Count; i++)
                retorno[i].Tipo = TraductorTipoEstablecimiento.ObtenerDto(lista[i].Tipo);
            return retorno;
        }


        /// <summary> Metodo que Agrega la Venta de un contrato </summary>
        /// <param name="venta">Datos Para la insercion</param>
        /// <returns>true si realizo la insercion</returns>
        [WebMethod(Description = "Metodo que Agrega la Venta de un contrato.")]
        public bool AgregarVenta(VentaDto venta)
        {
            var obj = TraductorVenta.ObtenerEntidad(venta);
            obj.Contrato = TraductorContrato.ObtenerEntidad(venta.Contrato);
            return _logica.AgregarEditarVenta(obj);
        }


        /// <summary> Metodo que Consulta las Venta de un contrato </summary>
        /// <param name="contrato">Datos Para la consulta</param>
        /// <param name="fechaInicio"> </param>
        /// <param name="fechaFin"> </param>
        /// <returns>Lista de Ventas del contrato</returns>
        [WebMethod(Description = "Metodo que Consulta las Venta de un contrato.")]
        public List<VentaDto> ConsultarVentasContrato(ContratoDto contrato, DateTime fechaInicio, DateTime fechaFin)
        {
            var obj = (contrato == null) ? null : TraductorContrato.ObtenerEntidad(contrato);
            var lista = _logica.ConsultarVentasContratos(obj, fechaInicio, fechaFin);
            var retorno = TraductorVenta.ObtenerListaDto(lista);
            for (var i = 0; i < lista.Count; i++)
            {
                retorno[i].Contrato = TraductorContrato.ObtenerDto(lista[i].Contrato);
                retorno[i].Contrato.Cliente = TraductorCliente.ObtenerDto(lista[i].Contrato.Cliente);
                retorno[i].Contrato.Establecimiento = TraductorEstablecimiento.ObtenerDto(lista[i].Contrato.Establecimiento);
            }
            return retorno;
        }


        /// <summary> Metood que consulta la lista de poliza segun los parametros indicados </summary>
        /// <param name="obj">Parametros para la busqueda</param>
        /// <returns>Lista de Poliza</returns>
        [WebMethod(Description = "Metood que consulta la lista de poliza segun los parametros indicados .")]
        public List<PolizaDto> ConsultarListaPoliza(ContratoDto obj)
        {

            var contrato = TraductorContrato.ObtenerEntidad(obj);
            if (obj.Establecimiento != null)
                contrato.Establecimiento = TraductorEstablecimiento.ObtenerEntidad(obj.Establecimiento);
            var lista = _logica.ConsultarListaPoliza(contrato);
            var retorno = TraductorPoliza.ObtenerListaDto(lista);
            for (var i = 0; i < lista.Count; i++)
            {
                retorno[i].Contratos = new List<ContratoDto> {TraductorContrato.ObtenerDto(lista[i].Contratos[0])};
                retorno[i].Contratos[0].Cliente = TraductorCliente.ObtenerDto(lista[i].Contratos[0].Cliente);
                retorno[i].Contratos[0].Establecimiento = TraductorEstablecimiento.ObtenerDto(lista[i].Contratos[0].Establecimiento);
            }
            return retorno;
        }


        /// <summary> Metodo que Agrega o edita la lista de proyeccion de un contrato </summary>
        /// <param name="listaAgregar">Lista a agregar</param>
        /// <param name="listaEliminar">Lista A eliminar</param>
        /// <returns>true si realizo la operacion false sino</returns>
        public bool AgregarEditarProyeccion(List<ProyeccionDto> listaAgregar, List<ProyeccionDto> listaEliminar)
        {
            var listaNueva = TraductorProyeccion.ObtenerListaEntidad(listaAgregar);
            IList<Proyeccion> listaVieja = null;

            if (listaEliminar != null)
            {
                listaVieja = TraductorProyeccion.ObtenerListaEntidad(listaEliminar);

                for (int i = 0; i < listaVieja.Count; i++)
                    listaVieja[i].Contrato = TraductorContrato.ObtenerEntidad(listaEliminar[i].Contrato);
            }
            for (int i = 0; i < listaNueva.Count; i++)
                listaNueva[i].Contrato = TraductorContrato.ObtenerEntidad(listaAgregar[i].Contrato);
            
            var resultado = _logica.AgregarEditarProyeccion(listaNueva, listaVieja);
            return resultado;
        }

        /// <summary> Metood que consulta la lista de proyeccion de un contrato </summary>
        /// <param name="obj">Parametros para la busqueda</param>
        /// <returns>Lista de Poliza</returns>
        [WebMethod(Description = "Metood que consulta la lista de proyeccion de un contrato")]
        public List<ProyeccionDto> ConsultarProyeccion(ContratoDto obj)
        {
            var contrato = TraductorContrato.ObtenerEntidad(obj);
            var lista = TraductorProyeccion.ObtenerListaDto(_logica.ConsultarProyeccion(contrato));

            foreach (var dto in lista)
                dto.Contrato = obj;
            return lista;
        }


        /// <summary> Metodo que consulta los canon por contrato y por fecha </summary>
        /// <param name="contrato">Datos del contrato a consultar</param>
        /// <param name="fecha">fecha inicio de la consulta</param>
        /// <returns>Lista de canon</returns>
        [WebMethod(Description = "Metodo que consulta los canon por contrato y por fecha ")]
        public List<ContratoPensionDto> ConsultarCanon(ContratoDto contrato, DateTime fecha)
        {
            var obj = TraductorContrato.ObtenerEntidad(contrato);
            obj.Establecimiento = TraductorEstablecimiento.ObtenerEntidad(contrato.Establecimiento);
            List<ContratoPension> lista = _logica.ConsultarCanon(obj, fecha);
            List<ContratoPensionDto> retorno = TraductorContratoPension.ObtenerListaDto(lista);
            foreach (var dto in retorno)
                dto.Contrato = contrato;
            return retorno;
        }


        /// <summary> Metodo que agrega a base de datos los parametros capturados en el formulario de agregar establecimiento. </summary>
        /// <param name="establecimiento">informacion a insertar en base de datos</param>
        /// <returns>true si inserto, false en el caso contrario</returns>
        [WebMethod(Description = "Metodo que Agrega o edita la informacion de un establecimientos .")]
        public bool AgregarEditarEstablecimiento(EstablecimientoDto establecimiento)
        {
            var obj = TraductorEstablecimiento.ObtenerEntidad(establecimiento);
            obj.Tipo = TraductorTipoEstablecimiento.ObtenerEntidad(establecimiento.Tipo);
            return _logica.AgregarEditarEstablecimiento(obj);
        }

        #endregion
    }
}
